/*******************************************************************************
 * This file is part of blueprint4j www.blueprint4j.org.
 * 
 *     blueprint4j is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     blueprint4j is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with blueprint4j. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package blueprint4j.utils;

import java.io.*;

public abstract class Logging {
   static public final Level DEV = new Level("Dev");
	static public final Level TRACE = new Level("Trace");
	static public final Level DEBUG = new Level("Debug");
	static public final Level CRITICAL = new Level("Critical");
	static public final Level COMM = new Level("Comm");
	static public final Level MESSAGE = new Level("Message");
	
   boolean log_dev = false;
	boolean log_debug = true;
	boolean log_trace = true;
	boolean log_critical = true;
	boolean log_comm = false;
	boolean log_message = false;

	public Logging(boolean debug, boolean trace, boolean critical) {
		log_debug = debug;
		log_trace = trace;
		log_critical = critical;
	}

	public Logging(boolean debug, boolean trace, boolean critical,boolean comm) {
		log_debug = debug;
		log_trace = trace;
		log_critical = critical;
		log_comm = comm;
	}

   public Logging(boolean debug, boolean dev,boolean trace, boolean critical,boolean comm) {
		log_debug = debug;
		log_dev = dev;
		log_trace = trace;
		log_critical = critical;
		log_comm = comm;
	}
   
	public Logging(boolean debug, boolean dev,boolean trace, boolean critical,boolean comm,boolean message) {
		log_debug = debug;
		log_dev = dev;
		log_trace = trace;
		log_critical = critical;
		log_comm = comm;
		log_message = message;
	}
	
	public void setTrace(boolean flag){
		log_trace=flag;
	}

	public void setDebug(boolean flag){
		log_debug=flag;
	}

	public void setCritical(boolean flag){
		log_critical=flag;
	}

	public void setComm(boolean flag){
		log_comm=flag;
	}

	public void setMessage(boolean flag) {
		log_message = flag;
	}
	/**
	* close and flush any log destinations
	*/
	public void close(){
	}

	final public void writeLog( Level lvl, long thread_id,String description, Throwable exception) {
		String detail = "";
		StackTraceElement[] stack_traces = exception.getStackTrace();
		for (int i = 0;i < stack_traces.length;i++) {
			detail += stack_traces[i].toString() + "\r";
		}
		writeLog(lvl,thread_id,description,exception.getMessage() + "\r" + detail);
	}

	final public void writeLog( Level lvl, long thread_id,String description, String details) {
      if (lvl == DEV && log_dev) {
			write(DEV.toString(),thread_id,description, details);
		}
		if (lvl == TRACE && log_trace) {
			write(TRACE.toString(),thread_id,description, details);
		}
		if (lvl == DEBUG && log_debug) {
			write(DEBUG.toString(),thread_id,description, details);
		}
		if (lvl == CRITICAL && log_critical) {
			write(CRITICAL.toString(),thread_id,description, details);
			ThreadSchedule.haltBlocking();
		}
		if (lvl == COMM && log_comm) {
			write(COMM.toString(),thread_id,description, details);
		}
		if (lvl == MESSAGE && log_message) {
			write(MESSAGE.toString(),thread_id,description, details);
		}
	}

	abstract public void write(String level,long thread_id,String description, String details);

	public abstract LogDataUnitVector findLogs(Integer tid,java.util.Date from_date,java.util.Date to_date,Logging.Level levels[]) throws IOException;

	static public class Level {
		private String name;

		Level(String p_name){
			name=p_name;
		}

		public String toString(){
			return name;
		}
	}
}

